<!--
// Muaz Khan     - www.MuazKhan.com
// MIT License   - www.WebRTC-Experiment.com/licence
// Experiments   - github.com/muaz-khan/WebRTC-Experiment
-->

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>RecordRTC over Node.js</title>
    <script>
    if (location.href.indexOf('file:') == 0) {
        document.write('<h1 style="color:red;">Please load this HTML file on HTTP or HTTPS.</h1>');
    }
    </script>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <link rel="author" type="text/html" href="https://plus.google.com/+MuazKhan">
    <meta name="author" content="Muaz Khan">
    <script src="https://www.webrtc-experiment.com/RecordRTC.js">
    </script>
    <style>
    html {
        background-color: #f7f7f7;
    }
    
    body {
        background-color: white;
        border: 1px solid rgb(15, 158, 238);
        margin: 1% 35%;
        text-align: center;
    }
    
    hr {
        border: 0;
        border-top: 1px solid rgb(15, 158, 238);
    }
    
    a {
        color: #2844FA;
        text-decoration: none;
    }
    
    a:hover,
    a:focus {
        color: #1B29A4;
    }
    
    a:active {
        color: #000;
    }
    
    audio,
    video {
        border: 1px solid rgb(15, 158, 238);
        width: 94%;
    }
    
    button[disabled],
    input[disabled] {
        background: rgba(216, 205, 205, 0.2);
        border: 1px solid rgb(233, 224, 224);
    }
    </style>
</head>

<body>
    <h1><a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/RecordRTC">RecordRTC</a> <a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/RecordRTC/RecordRTC-to-Nodejs">over Node.js</a>
    </h1>
    <p>
        <video></video>
    </p>
    <hr />

    <div>
        <label id="percentage">0%</label>
        <progress id="progress-bar" value="0"></progress>
        <br />
    </div>

    <hr />

    <div>
        <button id="btn-start-recording">Start Recording</button>
        <button id="btn-stop-recording" disabled="">Stop Recording</button>
    </div>

    <script>
    // fetching DOM references
    var btnStartRecording = document.querySelector('#btn-start-recording');
    var btnStopRecording = document.querySelector('#btn-stop-recording');

    var videoElement = document.querySelector('video');

    var progressBar = document.querySelector('#progress-bar');
    var percentage = document.querySelector('#percentage');
    </script>

    <script>
    // global variables
    var currentBrowser = !!navigator.mozGetUserMedia ? 'gecko' : 'chromium';

    var fileName;
    var audioRecorder;
    var videoRecorder;

    // Firefox can record both audio/video in single webm container
    // Don't need to create multiple instances of the RecordRTC for Firefox
    // You can even use below property to force recording only audio blob on chrome
    // var isRecordOnlyAudio = true;
    var isRecordOnlyAudio = !!navigator.mozGetUserMedia;

    // if recording only audio, we should replace "HTMLVideoElement" with "HTMLAudioElement"
    if (isRecordOnlyAudio && currentBrowser == 'chromium') {
        var parentNode = videoElement.parentNode;
        parentNode.removeChild(videoElement);

        videoElement = document.createElement('audio');
        videoElement.style.padding = '.4em';
        videoElement.controls = true;
        parentNode.appendChild(videoElement);
    }
    </script>

    <script>
    // reusable helpers

    // this function submits both audio/video or single recorded blob to nodejs server
    function postFiles(audio, video) {
        // getting unique identifier for the file name
        fileName = generateRandomString();

        // this object is used to allow submitting multiple recorded blobs
        var files = {};

        // recorded audio blob
        files.audio = {
            name: fileName + '.' + audio.blob.type.split('/')[1],
            type: audio.blob.type,
            contents: audio.dataURL
        };

        if (video) {
            files.video = {
                name: fileName + '.' + video.blob.type.split('/')[1],
                type: video.blob.type,
                contents: video.dataURL
            };
        }

        files.uploadOnlyAudio = !video;

        videoElement.src = '';
        videoElement.poster = '/ajax-loader.gif';

        xhr('/upload', JSON.stringify(files), function(_fileName) {
            var href = location.href.substr(0, location.href.lastIndexOf('/') + 1);
            videoElement.src = href + 'uploads/' + _fileName;
            videoElement.play();
            videoElement.muted = false;
            videoElement.controls = true;

            var h2 = document.createElement('h2');
            h2.innerHTML = '<a href="' + videoElement.src + '">' + videoElement.src + '</a>';
            document.body.appendChild(h2);
        });

        if (mediaStream) mediaStream.stop();
    }

    // XHR2/FormData
    function xhr(url, data, callback) {
        var request = new XMLHttpRequest();
        request.onreadystatechange = function() {
            if (request.readyState == 4 && request.status == 200) {
                callback(request.responseText);
            }
        };

        request.upload.onprogress = function(event) {
            progressBar.max = event.total;
            progressBar.value = event.loaded;
            progressBar.innerHTML = 'Upload Progress ' + Math.round(event.loaded / event.total * 100) + "%";
        };

        request.upload.onload = function() {
            percentage.style.display = 'none';
            progressBar.style.display = 'none';
        };
        request.open('POST', url);
        request.send(data);
    }

    // generating random string
    function generateRandomString() {
        if (window.crypto) {
            var a = window.crypto.getRandomValues(new Uint32Array(3)),
                token = '';
            for (var i = 0, l = a.length; i < l; i++) token += a[i].toString(36);
            return token;
        } else {
            return (Math.random() * new Date().getTime()).toString(36).replace(/\./g, '');
        }
    }

    // when btnStopRecording is clicked
    function onStopRecording() {
        audioRecorder.getDataURL(function(audioDataURL) {
            var audio = {
                blob: audioRecorder.getBlob(),
                dataURL: audioDataURL
            };

            // if record both wav and webm
            if (!isRecordOnlyAudio) {
                videoRecorder.getDataURL(function(videoDataURL) {
                    var video = {
                        blob: videoRecorder.getBlob(),
                        dataURL: videoDataURL
                    };

                    postFiles(audio, video);
                });
            }

            // if record only audio (either wav or ogg)
            if (isRecordOnlyAudio) postFiles(audio);
        });
    }
    </script>

    <script>
    var mediaStream = null;
    // reusable getUserMedia
    function captureUserMedia(success_callback) {
        var session = {
            audio: true,
            video: true
        };

        navigator.getUserMedia(session, success_callback, function(error) {
            alert(JSON.stringify(error));
        });
    }
    </script>

    <script>
    // UI events handling
    btnStartRecording.onclick = function() {
        btnStartRecording.disabled = true;

        captureUserMedia(function(stream) {
            mediaStream = stream;

            videoElement.src = window.URL.createObjectURL(stream);
            videoElement.play();
            videoElement.muted = true;
            videoElement.controls = false;

            // it is second parameter of the RecordRTC
            var audioConfig = {};
            if (!isRecordOnlyAudio) {
                audioConfig.onAudioProcessStarted = function() {
                    // invoke video recorder in this callback
                    // to get maximum sync
                    videoRecorder.startRecording();
                };
            }

            audioRecorder = RecordRTC(stream, audioConfig);

            if (!isRecordOnlyAudio) {
                // it is second parameter of the RecordRTC
                var videoConfig = {
                    type: 'video'
                };
                videoRecorder = RecordRTC(stream, videoConfig);
            }

            audioRecorder.startRecording();

            // enable stop-recording button
            btnStopRecording.disabled = false;
        });
    };


    btnStopRecording.onclick = function() {
        btnStartRecording.disabled = false;
        btnStopRecording.disabled = true;

        if (isRecordOnlyAudio) {
            audioRecorder.stopRecording(onStopRecording);
        }

        if (!isRecordOnlyAudio) {
            audioRecorder.stopRecording(function() {
                videoRecorder.stopRecording(function() {
                    onStopRecording();
                });
            });
        }
    };
    </script>

    <script>
    window.onbeforeunload = function() {
        startRecording.disabled = false;
    };
    </script>
    <footer style="width:100%;position: fixed; right: 0; text-align: center;color:red;">
        <a href="https://www.WebRTC-Experiment.com">www.WebRTC-Experiment.com</a>
    </footer>
</body>

</html>